<?php
// +----------------------------------------------------------------------
// | ThinkBLOG (Build on ThinkPHP)
// +----------------------------------------------------------------------
// | @link ( http://www.yurnero.net )
// +----------------------------------------------------------------------
// | @licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | @author nicholas <nicholasinlove@126.com>
// +----------------------------------------------------------------------
// | $Id: ThinkBLOG.class.php 6 2011-09-17 11:31:23Z nicholasinlove1986@gmail.com $
// +----------------------------------------------------------------------


class ThinkBLOG {
	
	public $session = NULL;
	public $var = array ();
	public $init_user = true;
	public $init_session = true;
	public $init_cron = true;
	public $init_misc = true;
	public $initated = false;
	private static $_instance = NULL;
	
	public static function getInstance() {
		if (NULL === self::$_instance) {
			self::$_instance = new ThinkBLOG ();
		}
		return self::$_instance;
	}
	
	private function __construct() {
		$this->_init_env ();
		$this->_init_options ();
		$this->_init_input ();
		$this->_init_output ();
	}
	
	public function init() {
		if (! $this->initated) {
			$this->_init_users ();
			$this->_init_session ();
			$this->_init_cron ();
			$this->_init_misc ();
			$this->_init_count ();
		}
		$this->initated = true;
	}
	
	private function _init_env() {
		
		define ( 'TIMESTAMP', tgmtime () );
		
		global $_T;
		$_T = array (
			'userid' => 0,
			'username' => '',
			'roleid' => 0,
			'sid' => '',
			'formhash' => '',
			'timestamp' => TIMESTAMP,
			'users' => array (),
			'clientip' => tget_client_ip (),
			'referer' => '',
			'authkey' => '',
			'PHP_SELF' => '',
			'siteurl' => '',
			'cookie' => array (),
			'session' => array (),
			'action' => array (
				'group' => 0,
				'module' => 0,
				'action' => 0,
				'postid' => 0,
			),
		);
		
		$_T ['PHP_SELF'] = htmlspecialchars ( $_SERVER ['SCRIPT_NAME'] ? $_SERVER ['SCRIPT_NAME'] : $_SERVER ['PHP_SELF'] );
		$sitepath = substr ( $_T ['PHP_SELF'], 0, strrpos ( $_T ['PHP_SELF'], '/' ) );
		$_T ['siteurl'] = htmlspecialchars ( 'http://' . $_SERVER ['HTTP_HOST'] . $sitepath . '/' );
		
		$this->var = & $_T;
	}
	
	private function _init_options() {
		$data = S ( 'options' );
		if (empty ( $data )) {
			$data = M ( 'Options' )->select ();
			foreach ( $data as $key => $row ) {
				$data [$row ['name']] = $row ['value'];
				unset ( $data [$key] );
			}
			S ( 'options', $data );
		}
		C ( $data );
		
		if (! C ( 'authkey' )) {
			C ( 'authkey', md5 ( C ( 'COOKIE_PREFIX' ) . C ( 'DB_NAME' ) ) );
		}
		
		//C ( 'COOKIE_PREFIX', C ( 'COOKIE_PREFIX' ) . substr ( md5 ( C ( 'COOKIE_PATH' ) . '|' . C ( 'COOKIE_DOMAIN' ) ), 0, 4 ) . '_' );
		

		$this->var ['authkey'] = md5 ( C ( 'authkey' ) );
		define ( 'VERHASH', C ( 'verhash' ) );
	}
	
	private function _init_input() {
		$prelength = strlen ( C ( 'COOKIE_PREFIX' ) );
		foreach ( $_COOKIE as $key => $val ) {
			if (substr ( $key, 0, $prelength ) == C ( 'COOKIE_PREFIX' )) {
				$this->var ['cookie'] [substr ( $key, $prelength )] = $val;
			}
		}
		
		$this->var ['sid'] = $this->var ['cookie'] ['sid'] = isset ( $this->var ['cookie'] ['sid'] ) ? htmlspecialchars ( $this->var ['cookie'] ['sid'] ) : '';
		$this->var ['inajax'] = tis_ajax () ? 1 : 0;
		$this->var ['action'] ['group'] = GROUP_NAME;
		$this->var ['action'] ['module'] = MODULE_NAME;
		$this->var ['action'] ['action'] = ACTION_NAME;
		$this->var ['action'] ['postid'] = (! empty ( $this->r->postid ) && is_numeric ( $this->r->postid )) ? $this->r->filter ( 'int' )->postid : 0;
	}
	
	private function _init_output() {
		if (! empty ( $_SERVER ['HTTP_ACCEPT_ENCODING'] ) && strpos ( $_SERVER ['HTTP_ACCEPT_ENCODING'], 'gzip' ) === false) {
			C ( 'gzip', 0 );
		}
		
		$allowgzip = C ( 'gzip' ) && function_exists ( 'ob_gzhandler' ) && empty ( $this->var ['inajax'] );
		ob_start ( $allowgzip ? 'ob_gzhandler' : NULL );
	}
	
	private function _init_session() {
		$this->session = new Sessions ();
		if ($this->init_session) {
			$this->session->init ( $this->var ['cookie'] ['sid'], $this->var ['clientip'], $this->var ['userid'] );
			$this->var ['sid'] = $this->session->sid;
			$this->var ['session'] = $this->session->var;
			
			if ($this->var ['sid'] != $this->var ['cookie'] ['sid']) {
				cookie ( 'sid', $this->var ['sid'], 86400 );
			}
			
			if ($this->session->isnew) {
				//if (ipbanned ( $this->var ['clientip'] )) {
			//$this->session->set ( 'roleid', 6 );
			//}
			}
			
			if ($this->session->get ( 'roleid' ) == 6) {
				$this->var ['users'] ['roleid'] = 6;
				tmessage ( L ( '_USER_BANNED_' ) );
			}
			
			if ($this->var ['userid'] && ($this->session->isnew || ($this->session->get ( 'lastactivity' ) + 600) < TIMESTAMP)) {
				$this->session->set ( 'lastactivity', TIMESTAMP );
			}
		
		}
	}
	
	private function _init_users() {
		if ($this->init_user) {
			if (! empty ( $_REQUEST ['auth'] )) {
				$auth = htmlspecialchars ( trim ( $_REQUEST ['auth'] ) );
			} else if (! empty ( $this->var ['cookie'] ['auth'] )) {
				$auth = $this->var ['cookie'] ['auth'];
			}
			$auth = taddslashes ( explode ( "\t", tauthcode ( $auth, 'DECODE' ) ) );
			list ( $password, $userid ) = empty ( $auth ) || count ( $auth ) < 2 ? array ('', '' ) : $auth;
			
			if ($userid) {
				$users = M ( 'Users' )->getByUserid ( $userid );
			}
			
			if (! empty ( $users ) && $users ['password'] == $password) {
				$this->var ['users'] = $users;
			} else {
				$user = array ();
				$this->_init_guest ();
			}
		
		} else {
			$this->_init_guest ();
		}
		
		if (empty ( $this->var ['cookie'] ['lastvisit'] )) {
			$this->var ['users'] ['lastvisit'] = TIMESTAMP - 3600;
			cookie ( 'lastvisit', TIMESTAMP - 3600, 86400 * 30 );
		} else {
			$this->var ['users'] ['lastvisit'] = $this->var ['cookie'] ['lastvisit'];
		}
		
		$this->var ['userid'] = $this->var ['users'] ['userid'];
		$this->var ['username'] = addslashes ( $this->var ['users'] ['username'] );
		$this->var ['roleid'] = $this->var ['users'] ['roleid'];
	}
	
	private function _init_guest() {
		$this->var ['users'] = array ('userid' => 0, 'username' => '', 'roleid' => 5 );
	}
	
	private function _init_cron() {
		//TODO
	}
	
	private function _init_misc() {
		if (! $this->init_misc) {
			return false;
		}
		$this->var ['formhash'] = tformhash ();
		define ( 'FORMHASH', $this->var ['formhash'] );
		
		if ($this->init_user) {
			if ($this->var ['users'] ['status'] == - 1) {
				tmessage ( L ( '_USER_BANNED_' ) );
			}
		}
		
		// TODO
		// ip access
		

		if (C ( 'closed' ) == 1 && $this->var ['roleid'] != 1) {
			header ( 'Content-type:text/html;charset=utf-8' );
			die ( '<div style="margin: 150px; text-align: center; font-size: 14px"><p>' . C ( 'title' ) . '</p><p>' . C ( 'close_comment' ) . '</p></div>' );
		}
	}
	
	private function _init_count() {
		$this->visitor ();
		$this->online ();
	}
	
	public function visitor() {
		$spiders = 'Bot|Crawl|Spider|slurp|sohu-search|lycos|robozilla';
		$browsers = 'MSIE|Netscape|Opera|Konqueror|Mozilla';
		if (! preg_match ( "/({$spiders})/", $_SERVER ['HTTP_USER_AGENT'] ) && preg_match ( "/($browsers)/", $_SERVER ['HTTP_USER_AGENT'] )) {
			if ($this->var ['clientip'] != $this->var ['cookie'] ['visitor']) {
				cookie ( 'visitor', $this->var ['clientip'], '86400' );
				$nowtime = date ( 'Ymd' );
				$model = D ( 'Options' );
				$dayTime = C ( 'dayTime' );
				if ($nowtime != $dayTime) {
					$data = array ();
					$data ['dayTime'] = $nowtime;
					$data ['todayVisited'] = 1;
					$model->setOptions ( $data );
				} else {
					$model->where ( "name='todayVisited'" )->setLazyInc ( 'value', 1, 60 );
				}
				$model->where ( "name='allVisited'" )->setLazyInc ( 'value', 1, 60 );
				S ( 'options', NULL );
			}
		}
	}
	
	public function online() {
		$onlineinfo = explode ( "\t", C ( 'onlineRecord' ) );
		if (empty ( $this->var ['cookie'] ['onlinenum'] )) {
			$onlinenum = $this->session->getOnlineCount ();
			if ($onlinenum > $onlineinfo [0]) {
				$data = array ();
				$data ['onlineRecord'] = $onlinenum . "\t" . TIMESTAMP;
				D ( 'Options' )->setOptions ( $data );
				S ( 'options', NULL );
			}
			cookie ( 'onlinenum', intval ( $onlinenum ), 300 );
		}
	}

}